using MediatR;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using SumerCoreDevOps.Application.Roles.Commands;
using SumerCoreDevOps.Application.Roles.Queries;
using SumerCoreDevOps.Domain.Entities;
using SumerCoreDevOps.Application.Dtos.Requests.Roles;
namespace SumerCoreDevOps.ControlApi.Controllers;

/// <summary>
/// 角色管理 API
/// 提供角色的增删改查、权限分配、用户分配等功能
/// </summary>
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class RoleController : ControllerBase
{
    private readonly IMediator _mediator;
    private readonly ILogger<RoleController> _logger;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="mediator">MediatR 中介者</param>
    /// <param name="logger">日志记录器</param>
    public RoleController(IMediator mediator, ILogger<RoleController> logger)
    {
        _mediator = mediator;
        _logger = logger;
    }

    /// <summary>
    /// 获取所有角色列表
    /// </summary>
    /// <returns>返回包含所有角色的列表,每个角色包括ID、角色名称、描述、创建时间、是否为系统角色等信息;如果发生错误则返回500状态码和错误详情</returns>
    /// <response code="200">成功返回角色列表</response>
    /// <response code="500">服务器内部错误</response>
    [HttpGet]
    [ProducesResponseType(typeof(List<Role>), 200)]
    public async Task<ActionResult<List<Role>>> GetAllRoles()
    {
        try
        {
            var roles = await _mediator.Send(new GetAllRolesQuery());
            return Ok(roles);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取角色列表失败");
            return StatusCode(500, new { message = "获取角色列表失败", error = ex.Message });
        }
    }

    /// <summary>
    /// 获取角色详细信息（包含权限）
    /// </summary>
    /// <param name="roleId">角色ID</param>
    /// <returns>返回包含角色基本信息和该角色拥有的所有权限列表的对象;如果角色不存在则返回404状态码和提示信息;发生错误时返回500状态码和错误详情</returns>
    /// <response code="200">成功返回角色信息</response>
    /// <response code="404">角色不存在</response>
    /// <response code="500">服务器内部错误</response>
    [HttpGet("{roleId}")]
    [ProducesResponseType(typeof(object), 200)]
    public async Task<ActionResult<object>> GetRoleById(long roleId)
    {
        try
        {
            var roleInfo = await _mediator.Send(new GetRoleByIdQuery(roleId));
            if (roleInfo == null)
            {
                return NotFound(new { message = "角色不存在" });
            }

            return Ok(roleInfo);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取角色详细信息失败: RoleId={RoleId}", roleId);
            return StatusCode(500, new { message = "获取角色信息失败", error = ex.Message });
        }
    }

    /// <summary>
    /// 获取角色下的所有用户
    /// </summary>
    /// <param name="roleId">角色ID</param>
    /// <returns>返回拥有该角色的所有用户列表,包含用户ID、用户名、邮箱、显示名称等信息;如果该角色下没有用户则返回空列表;发生错误时返回500状态码和错误详情</returns>
    /// <response code="200">成功返回用户列表</response>
    /// <response code="500">服务器内部错误</response>
    [HttpGet("{roleId}/users")]
    [ProducesResponseType(typeof(List<User>), 200)]
    public async Task<ActionResult<List<User>>> GetUsersByRoleId(long roleId)
    {
        try
        {
            var users = await _mediator.Send(new GetUsersByRoleIdQuery(roleId));
            return Ok(users);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取角色用户列表失败: RoleId={RoleId}", roleId);
            return StatusCode(500, new { message = "获取角色用户失败", error = ex.Message });
        }
    }

    /// <summary>
    /// 创建新角色
    /// </summary>
    /// <param name="request">创建角色请求</param>
    /// <returns>返回201状态码和新创建的角色完整信息对象,包括自动生成的角色ID、角色名称、描述、创建时间等字段;如果角色名称已存在则返回400状态码和错误提示;发生其他错误时返回500状态码和错误详情</returns>
    /// <response code="201">成功创建角色</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="500">服务器内部错误</response>
    [HttpPost]
    [ProducesResponseType(typeof(Role), 201)]
    public async Task<ActionResult<Role>> CreateRole([FromBody] CreateRoleRequest request)
    {
        try
        {
            var role = await _mediator.Send(new CreateRoleCommand(
                request.RoleName,
                request.Description,
                request.CreatedBy
            ));

            return CreatedAtAction(nameof(GetRoleById), new { roleId = role.Id }, role);
        }
        catch (InvalidOperationException ex)
        {
            return BadRequest(new { message = ex.Message });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "创建角色失败: RoleName={RoleName}", request.RoleName);
            return StatusCode(500, new { message = "创建角色失败", error = ex.Message });
        }
    }

    /// <summary>
    /// 删除角色
    /// </summary>
    /// <param name="roleId">角色ID</param>
    /// <returns>返回200状态码和成功提示信息;如果角色是系统角色或有用户正在使用则返回400状态码和不能删除的原因;如果角色不存在则返回404状态码;发生错误时返回500状态码和错误详情</returns>
    /// <response code="200">角色删除成功</response>
    /// <response code="400">角色不能删除（如系统角色或有关联用户）</response>
    /// <response code="404">角色不存在</response>
    /// <response code="500">服务器内部错误</response>
    [HttpDelete("{roleId}")]
    public async Task<ActionResult> DeleteRole(long roleId)
    {
        try
        {
            await _mediator.Send(new DeleteRoleCommand(roleId));
            return Ok(new { message = "角色删除成功" });
        }
        catch (InvalidOperationException ex)
        {
            return BadRequest(new { message = ex.Message });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "删除角色失败: RoleId={RoleId}", roleId);
            return StatusCode(500, new { message = "删除角色失败", error = ex.Message });
        }
    }

    /// <summary>
    /// 为角色分配权限
    /// </summary>
    /// <param name="roleId">角色ID</param>
    /// <param name="request">分配权限请求</param>
    /// <returns>返回200状态码和成功提示信息;如果角色不存在或权限ID无效则返回400状态码和错误提示;发生错误时返回500状态码和错误详情</returns>
    /// <response code="200">权限分配成功</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="404">角色不存在</response>
    /// <response code="500">服务器内部错误</response>
    [HttpPost("{roleId}/permissions")]
    public async Task<ActionResult> AssignPermissionsToRole(long roleId, [FromBody] AssignPermissionsRequest request)
    {
        try
        {
            await _mediator.Send(new AssignPermissionsToRoleCommand(
                roleId,
                request.PermissionIds,
                request.OperatedBy
            ));

            return Ok(new { message = "权限分配成功" });
        }
        catch (InvalidOperationException ex)
        {
            return BadRequest(new { message = ex.Message });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "为角色分配权限失败: RoleId={RoleId}", roleId);
            return StatusCode(500, new { message = "分配权限失败", error = ex.Message });
        }
    }

    /// <summary>
    /// 从角色移除权限
    /// </summary>
    /// <param name="roleId">角色ID</param>
    /// <param name="permissionId">权限ID</param>
    /// <returns>返回200状态码和成功提示信息;如果角色或权限不存在则返回400状态码和错误提示;发生错误时返回500状态码和错误详情</returns>
    /// <response code="200">权限移除成功</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="404">角色或权限不存在</response>
    /// <response code="500">服务器内部错误</response>
    [HttpDelete("{roleId}/permissions/{permissionId}")]
    public async Task<ActionResult> RevokePermissionFromRole(long roleId, long permissionId)
    {
        try
        {
            await _mediator.Send(new RevokePermissionFromRoleCommand(
                roleId,
                permissionId
            ));

            return Ok(new { message = "权限移除成功" });
        }
        catch (InvalidOperationException ex)
        {
            return BadRequest(new { message = ex.Message });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "从角色移除权限失败: RoleId={RoleId}, PermissionId={PermissionId}", roleId, permissionId);
            return StatusCode(500, new { message = "移除权限失败", error = ex.Message });
        }
    }

    /// <summary>
    /// 为用户分配角色
    /// </summary>
    /// <param name="request">分配角色请求</param>
    /// <returns>返回200状态码和成功提示信息;如果用户或角色不存在、用户已拥有该角色则返回400状态码和错误提示;发生错误时返回500状态码和错误详情</returns>
    /// <response code="200">角色分配成功</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="404">用户或角色不存在</response>
    /// <response code="500">服务器内部错误</response>
    [HttpPost("assign")]
    public async Task<ActionResult> AssignRoleToUser([FromBody] AssignRoleToUserRequest request)
    {
        try
        {
            await _mediator.Send(new AssignRoleToUserCommand(
                request.UserId,
                request.RoleId,
                request.OperatedBy
            ));

            return Ok(new { message = "角色分配成功" });
        }
        catch (InvalidOperationException ex)
        {
            return BadRequest(new { message = ex.Message });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "为用户分配角色失败: UserId={UserId}, RoleId={RoleId}", request.UserId, request.RoleId);
            return StatusCode(500, new { message = "分配角色失败", error = ex.Message });
        }
    }

    /// <summary>
    /// 从用户移除角色
    /// </summary>
    /// <param name="request">移除角色请求</param>
    /// <returns>返回200状态码和成功提示信息;如果用户或角色不存在、用户没有该角色则返回400状态码和错误提示;发生错误时返回500状态码和错误详情</returns>
    /// <response code="200">角色移除成功</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="404">用户或角色不存在</response>
    /// <response code="500">服务器内部错误</response>
    [HttpPost("revoke")]
    public async Task<ActionResult> RevokeRoleFromUser([FromBody] RevokeRoleFromUserRequest request)
    {
        try
        {
            await _mediator.Send(new RevokeRoleFromUserCommand(
                request.UserId,
                request.RoleId
            ));

            return Ok(new { message = "角色移除成功" });
        }
        catch (InvalidOperationException ex)
        {
            return BadRequest(new { message = ex.Message });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "从用户移除角色失败: UserId={UserId}, RoleId={RoleId}", request.UserId, request.RoleId);
            return StatusCode(500, new { message = "移除角色失败", error = ex.Message });
        }
    }
}
